﻿using FluentValidation;
using MediatR;
using PersonalWebsite.Core.Exceptions;

namespace PersonalWebsite.Core.Vaildate;

public class VaildateBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : notnull
{
    private readonly IEnumerable<IValidator<TRequest>> _validators;

    public VaildateBehavior(IEnumerable<IValidator<TRequest>> validators)
    {
        _validators = validators;
    }

    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        var failures = _validators.Select(c => c.Validate(request))
               .Where(c => !c.IsValid)
              .SelectMany(c => c.Errors)
              .Select(c => new
              {
                  c.PropertyName,
                  c.ErrorMessage
              });

        if (failures.Any())
        {
            var errors = failures.Select(c => new VaildateResult(c.PropertyName, c.ErrorMessage)).ToArray();

            throw new VaildateException(errors);
        }

        return await next();
    }
}
